package com.itheima.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;




/*
* 检查用户是否已经完成登录
* 目的:保证资源访问安全性，只有登录之后才能成功访问后台数据
* */
@WebFilter(urlPatterns = "/*")//
@Slf4j//记录日志
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //将请求和响应向下转型，为了能够调用一些子接口的特有方法
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
       //获取当前请求路径
        String uri = request.getRequestURI();//uri:/backend/index.html
        log.info("拦截到请求:{}",uri);
        //判断资源是否需要直接放行,比如登录请求，静态资源，则直接放行
        String[] strs={"/employee/login",
                "/employee/logout",
                "/backend/",
                "/front/",
                "/user/login",//移动端登录
                "/user/sendMsg"};//移动端发送短信
        for (String str : strs) {
            if (uri.contains(str)){
                filterChain.doFilter(request,response);
                return;
            }
        }
        //判断是否登录(因为那边的值为用户的id，所以这边要强转才能获取其id)
        Long empId = (Long) request.getSession().getAttribute("employee");
        if (empId!=null){
            //设置当前线程的id值
            BaseContext.setCurrentId(empId);
            log.info("线程id为 {}",empId);

            //如果登录则直接放行
            filterChain.doFilter(request,response);
            return;
        }

        Long userId = (Long) request.getSession().getAttribute("user");
        if (userId!=null){
            //设置当前线程的id值
            BaseContext.setCurrentId(userId);
            log.info("线程id为 {}",userId);

            //如果登录则直接放行
            filterChain.doFilter(request,response);
            return;
        }


        //如果没有登录则返回没有登录的错误，通过输出流方式向客户端页面响应数据
        //前端那边要同时满足code === 0和data.msg === 'NOTLOGIN',code在R error为0
        // 所以满足信息为"NOTLOGIN"就可以
        String json = JSON.toJSONString(R.error("NOTLOGIN"));
        response.getWriter().write(json);

    }
}

/*

目的: 保证资源访问安全性. 只有登录之后才能成功访问后台数据

登录验证流程分析:

1. 获取请求路径
2. 判断是否为需要直接放行的资源,如果是,则直接放行
3. 如果没有直接被放行, 判断是否已经登录,如果登录了,则放行
4. 如果没有登录,则响应未登录的错误提示给前端, 前端会跳转到登录页面

移动端登录前的前置工作:

1. 复制工具类 SMSUtils2 ValidateCodeUtils 坐标导入
2. 替换前台系统静态资源 : front
3. 修改登录验证的过滤器:
   1. 添加两个放行的资源
   2. 加入判断移动端登录的代码
      */

